#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

typedef struct s
{
	int val;
	struct s *next;	
}stuff;

stuff *head = NULL;
stuff *product;

void *Producer(void *arg)
{
	product = malloc(sizeof(stuff));
	product->val = rand()%10;

	pthread_mutex_lock(&mutex);
	product->next = head;
	head = product;
	pthread_mutex_unlock(&mutex);
	
	pthread_cond_signal(&cond);

	return NULL;	
}

void *Consumer(void *arg)
{
	int val;
	pthread_mutex_unlock(&mutex);
	while(head == NULL)//when two consumers wait for 'cond', the 'head' maybe NULL. So another consumer cannot object to 'cond', and thus here should be 'while' rather than 'if'. 
	{
		pthread_cond_wait(&cond, &mutex);
	}
	val = head->val;
	pthread_mutex_unlock(&mutex);
	
	printf("val : %d\n", val);	

	head = NULL;
	free(product);
	
	return NULL;
}

int main(int argc, char **argv)
{
	pthread_t Pthread;
	pthread_t Cthread;

	srand(time(NULL));

	pthread_create(&Pthread, NULL, Producer, NULL);
	pthread_create(&Cthread, NULL, Consumer, NULL);

	pthread_join(Pthread, NULL);
	pthread_join(Cthread, NULL);	

	pthread_cond_destroy(&cond);
	pthread_mutex_destroy(&mutex);	

	return 0;
}
